package org.goobs.csp;



import java.util.ArrayList;
import java.util.Collection;

public abstract class BinaryConstraint <E, F> implements IConstraint{

	private CSPVariable <E> tail;
	private CSPVariable <F> head;
	private boolean reflexive;
	
	public BinaryConstraint(CSPVariable <E> a, CSPVariable <F> b, boolean reflexive){
		this.tail = a;
		this.head = b;
		this.reflexive = reflexive;
	}
	
	protected CSPVariable <E> getA(){
		return tail;
	}
	
	protected CSPVariable <F> getB(){
		return head;
	}
	
	
	@SuppressWarnings("unchecked")
	public abstract boolean isSatisfied(CSPVariable tail, CSPVariable head);
	
	
	@SuppressWarnings("unchecked")
	public Collection <ICSPArc> generateArcs(CSP csp){
		Collection rtn = new ArrayList <ICSPArc>();
		
		ICSPArc dir1 = new ICSPArc() {
			@Override
			public boolean isOK() {
				if(tail.getValue() != null && head.getValue() != null){
					return isSatisfied(tail, head);
				}else{
					return true;
				}
			}
			@Override
			public CSPVariable getTail() {
				return tail;
			}
			@Override
			public CSPVariable getHead() {
				return head;
			}
		};
		rtn.add(dir1);
		
		if(!reflexive){
			return rtn;
		}
		
		ICSPArc dir2 = new ICSPArc() {
			@Override
			public boolean isOK() {
				if(tail.getValue() != null && head.getValue() != null){
					return isSatisfied(head, tail);
				}else{
					return true;
				}
			}
			@Override
			public CSPVariable getTail() {
				return head;
			}
			@Override
			public CSPVariable getHead() {
				return tail;
			}
		};
		rtn.add(dir2);
		
		return rtn;
	}
	
}
